package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.DmcWatchOldmanMapper;
import com.csun.cmny.provider.device.watch.WatchMessageHandler;
import com.csun.cmny.provider.device.watch.entity.WatchDataEntity;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.domain.DmcDevice;
import com.csun.cmny.provider.model.domain.DmcWatchOldman;
import com.csun.cmny.provider.model.dto.propertyManagement.SelectDeviceDataDto;
import com.csun.cmny.provider.model.dto.watch.BindDmcWatchOldmanDto;
import com.csun.cmny.provider.model.dto.watch.OldmanBindWatchReqDto;
import com.csun.cmny.provider.model.dto.watch.WatchPageQuery;
import com.csun.cmny.provider.model.vo.OldmanBedRoomBuildingVo;
import com.csun.cmny.provider.model.vo.propertyManagement.PropertyDataVo;
import com.csun.cmny.provider.model.vo.watch.DmcWatchVo;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.util.PublicUtil;
import com.csun.cmny.util.RedisKeyUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-01-24 09:26
 * @Description: the class dmc watch oldman service impl
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DmcWatchOldmanServiceImpl extends BaseService<DmcWatchOldman> implements DmcWatchOldmanService {

    @Resource
    private DmcWatchOldmanMapper dmcWatchOldmanMapper;
    @Resource
    private DmcDeviceService dmcDeviceService;
    @Resource
    private OmcRpcService omcRpcService;
    @Resource
    private DmcWatchConfigService dmcWatchConfigService;
    @Resource
    private DmcWatchDataService dmcWatchDataService;
    @Resource
    private DmcWatchAlarmClockService dmcWatchAlarmClockService;
    @Resource
    private DmcWatchSafetyRangeService dmcWatchSafetyRangeService;
    @Resource
    public RedisTemplate<String, Object> redisTemplate;
    @Resource
    private WatchMessageHandler watchMessageHandler;
    @Resource
    private DmcDeviceAlertService dmcDeviceAlertService;

    /**
     * bind dmc watch oldman
     *
     * @param bindDmcWatchOldmanDto bind dmc watch oldman dto
     * @return the int.
     */
    @Override
    public Integer bindDmcWatchOldman(BindDmcWatchOldmanDto bindDmcWatchOldmanDto) {

        Example example = new Example(DmcWatchOldman.class);
        Example.Criteria criteria = example.createCriteria();

        // 1.判断设备是否存在 && 设备是否为孝心手环
        DmcDevice dmcDevice = dmcDeviceService.checkDeviceIsWatchByDeviceId(bindDmcWatchOldmanDto.getDeviceId());
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610014, bindDmcWatchOldmanDto.getDeviceId());
        }

        // 2、校验老人Id是否存在
        // TODO 校验老人Id是否存在
        OldmanBedRoomBuildingVo oldmanBedRoomBuildingVo = omcRpcService
                .queryOldmanBedRoomBuildingByOldmanId(bindDmcWatchOldmanDto.getOldmanId());
        if (PublicUtil.isEmpty(oldmanBedRoomBuildingVo)) {
            // 老人不存在
            throw new DmcBizException(ErrorCodeEnum.DMC100610062);
        }

        bindDmcWatchOldmanDto.setOldmanName(oldmanBedRoomBuildingVo.getOldmanName());

        // 3、校验设备Id或老人Id是否已经
        criteria.andEqualTo("deviceId", bindDmcWatchOldmanDto.getDeviceId());
        example.or(example.createCriteria().andEqualTo("oldmanId", bindDmcWatchOldmanDto.getOldmanId()));
        DmcWatchOldman dmcWatchOldman = dmcWatchOldmanMapper.selectOneByExample(example);
        if (PublicUtil.isNotEmpty(dmcWatchOldman)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610012);
        }

        // 4、绑定设备 - 老人
        dmcWatchOldman = new DmcWatchOldman();
        BeanUtils.copyProperties(bindDmcWatchOldmanDto, dmcWatchOldman);
        Integer result = dmcWatchOldmanMapper.insertSelective(dmcWatchOldman);

        if (result > 0) { // 初始化消息手环数据

            // 5、初始化消息手环数据
            WatchDataEntity watchDataEntity = initWatchDataEntity(oldmanBedRoomBuildingVo, dmcDevice);
            String redisKey = RedisKeyUtil.getXxWatchKey(dmcDevice.getDeviceNo());
            redisTemplate.opsForValue().set(redisKey, watchDataEntity);

            // 5、初始化孝心手环配置
            dmcWatchConfigService.initDmcWatchConfig(dmcWatchOldman.getDeviceId());

            // 6、初始化孝心手环数据
            dmcWatchDataService.initDmcWatchData(dmcWatchOldman.getDeviceId());
        }

        return result;
    }

    private WatchDataEntity initWatchDataEntity(OldmanBedRoomBuildingVo oldmanBedRoomBuildingVo, DmcDevice dmcDevice) {

        WatchDataEntity watchDataEntity = new WatchDataEntity();
        watchDataEntity.setOldmanId(oldmanBedRoomBuildingVo.getOldmanId());
        watchDataEntity.setOldmanName(oldmanBedRoomBuildingVo.getOldmanName());
        watchDataEntity.setDeviceId(dmcDevice.getId());
        watchDataEntity.setDeviceNo(dmcDevice.getDeviceNo());
        watchDataEntity.setGroupId(dmcDevice.getGroupId());

        return watchDataEntity;
    }

    /**
     * break dmc watch oldman by device id
     *
     * @param deviceId device id
     * @return the int.
     */
    @Override
    public Integer breakDmcWatchOldmanByDeviceId(Long deviceId) {

        // 1.判断设备是否存在 && 设备是否为孝心手环
        DmcDevice dmcDevice = dmcDeviceService.checkDeviceIsWatchByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610014, deviceId);
        }

        // 2、根据设备Id删除与老人的绑定
        Example example = new Example(DmcWatchOldman.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("deviceId", deviceId);

        Integer result = dmcWatchOldmanMapper.deleteByExample(example);
        if (result > 0) {
            // 初始化手环配置 -- 在设备初次上线的时候初始化配置
//            watchMessageHandler.initConfig(dmcDevice.getDeviceNo());

            // 3、移除孝心手环网络接口
            watchMessageHandler.clear(dmcDevice.getDeviceNo());

            // 4、移除孝心手环数据
            dmcWatchDataService.removeDmcWatchData(deviceId);

            // 5、移除孝心手环配置
            dmcWatchConfigService.removeDmcWatchConfig(deviceId);

            // 6、移除孝心手环提醒
            dmcWatchAlarmClockService.removeDmcWatchAlarmClock(deviceId);

            // 7、移除孝心手环安全区域
            dmcWatchSafetyRangeService.removeDmcSafetyRange(deviceId);

            // 8、移除报警
            dmcDeviceAlertService.deleteByDeviceId(deviceId);

            // 清除redisKey
            String redisKey = RedisKeyUtil.getXxWatchKey(dmcDevice.getDeviceNo());
            redisTemplate.delete(redisKey);
        }

        return result;
    }

    /**
     * break dmc watch old man by oldman id
     *
     * @param oldmanId oldman id
     * @return the int.
     */
    @Override
    public Integer breakDmcWatchOldmanByOldmanId(Integer oldmanId) {

        // 0、接口暂不实现

        // 1、校验老人Id是否存在

        // 2、校验老人Id是否绑定孝心手环

        // 3、校验孝心手环是否存在

        // 4、根据老人Id与设备绑定

        // 3、移除孝心手环网络接口

        // 4、移除孝心手环数据

        // 5、移除孝心手环配置

        return null;
    }

    /**
     * query watch list with page
     *
     * @param watchPageQuery watch page query
     *
     * @return the page info.
     */
    @Override
    public PageInfo queryWatchListWithPage(WatchPageQuery watchPageQuery) {

        PageHelper.startPage(watchPageQuery.getPageNum(), watchPageQuery.getPageSize());

        List<DmcWatchVo> dmcWatchVoList = dmcWatchOldmanMapper.queryWatchListWithPage(watchPageQuery);

        return new PageInfo<>(dmcWatchVoList);
    }

    /**
     * query oldman bind watch list
     *
     * @param oldmanBindWatchReqDto oldman bind watch req dto
     * @return the list.
     */
    @Override
    public List<Integer> queryOldmanBindWatchList(OldmanBindWatchReqDto oldmanBindWatchReqDto) {

        return dmcWatchOldmanMapper.queryOldmanBindWatchList(oldmanBindWatchReqDto);
    }

    @Override
    public List<PropertyDataVo> selectDeviceData(SelectDeviceDataDto selectDeviceDataDto) {
        return dmcWatchOldmanMapper.selectDeviceData(selectDeviceDataDto);
    }
}
